package edu.spsu.cs4253;


import java.io.*;
import java.net.*;

public class UDPRouter {

 
	
	/*
     *  Routing Table holds 10 nodes.
     *  Each node has an ip address as element [0]
     *  and a port # as element [1]
     *  
     */
	String [][] ipArray = new String[10][2];
    DatagramPacket receivePacket = null;   
    DatagramSocket serverSocket = null;
    DatagramSocket outgoingServerSocket = null;    
    byte[] receiveData = new byte[1024]; 
    byte[] sendData  = new byte[1024]; 
    InetAddress ipAddress = null; 

    /**
     * default constructor
     * @return 
     */
    public UDPRouter() {
        try {
            serverSocket = new DatagramSocket();
            ipAddress = serverSocket.getInetAddress();
            }
        catch( SocketException e ) {
            System.out.println( e.getMessage() );
            }
        
    }
    
   
  
    /**
     * receives data from clients and prepare it for forwarding
     * 
     * @return void
     */
    public void getAndBuildData(DatagramPacket dp) throws Exception {
       
       while(true) {
            receivePacket = dp;
            serverSocket.receive(receivePacket); 		   
            sendData = receivePacket.getData() ;
             
            System.out.println("From getAndBuildData() Method: " + receivePacket.toString());
            addIP();
            
            // Loop through the Routing Table to find an IP match
            for( int i = 0 ; i < ipArray.length; i++ ) {

              if( ipArray[i][0].equals(  ipAddress ) ) {
                  this.Router( i, sendData, ipAddress, ipArray[i][1] );
              }                
          }
            
       }
            
    }
    /**Updates ip routing table array
     * 
     * @return void
     */
    public void addIP() {
 	
    	//String [][]array = new String [10][3];
    	while (ipArray.length != 10){
    		int i = ipArray.length;
    		String portNum = Integer.toString(receivePacket.getPort());
    		InetAddress tempHost = receivePacket.getAddress();
        	ipArray [i][0]= "" + tempHost;
        	ipArray [i][1]= portNum;
        		}
    		
    	}
 
    /**
     * determines which interface to bind to.
     * @param int link - the interface
     * @param byte message - the message to be sent
     * @param Object ipAddress - the ip address the message to be sent to.
     * @param String ports - the port number
     *    String port = Integer.toString(portNum);
     * @return void
     */
    public void Router (int link, byte[] message, InetAddress ipAddress,
        String ports) throws Exception {
        
        int port = Integer.parseInt( ports );

        switch(link) {
            case 0:
                this.transferMessage( message, ipAddress, port );
                break;
                          
            case 1:
                this.transferMessage( message, ipAddress, port );
                break;
            
            case 2:
                this.transferMessage( message, ipAddress, port );
                break;
             
            case 3:
                this.transferMessage( message, ipAddress, port );
                break;
            
            case 4:
                this.transferMessage( message, ipAddress, port );
                break;
            
            case 5:
                this.transferMessage( message, ipAddress, port );
                break;
                
            case 6:
                this.transferMessage( message, ipAddress, port );
                break;
                
            case 7:
                this.transferMessage( message, ipAddress, port );
                break;
            
            
            default : 
                System.out.println("No interface to bind to");
                break;
	}
        
    }
    
    /**
     * sends the message to the destination IP
     * @param byte message - the data to be sent
     * @param Object ipAddress - the destination IP address
     * @param int port - the port number
     *
     * @return void
     */
    public void transferMessage( byte[] message,  InetAddress ipAddress, int port ) {
        
        try {
            outgoingServerSocket = new DatagramSocket(port);
        
        }catch( SocketException e ) {
            System.out.println( e.getMessage() );
        }
        
        try {
        	    
            DatagramPacket sendPacket = new DatagramPacket( message, message.length, 
                ipAddress, port );

            outgoingServerSocket.send(sendPacket);

        }catch( IOException e ) {
            System.out.println( e.getMessage() );
        }
    }




}
